#/usr/bin/python
# -*- coding: utf-8 -*-

from strategy import *

## Parent class:
class Analysis():
    '''
       Parent class of analysis classes. 
    '''
    def __init__(self, incrementManager, solvingStrategy):
        self.incrementManager = incrementManager
        self.solvingStrategy = solvingStrategy
        self.lhslist = []
        self.coeflhs = []
        self.rhslist = []
        self.coefrhs = []
        self.iterative = False
#        self.error = errorMeasure
        self.tol = 1.e-3
    
    def __repr__(self):
        return 'unimplemented analysis'
    # set    
    def setSolvingStrategy(self,solvingStrategy):
        self.solvingStrategy = solvingStrategy
                
    def setIncrementManager(self, incrementManager):
        self.incrementManager = incrementManager
    
    def setTol(self, tol):
        
        self.tol = tol
        
    def start(self):
        ''' Method to start analysis
        '''
        raise NotImplementedError
    
    def getOperators(self):
        
        return self.lhslist, self.rhslist   
    
        
## Child classes:

# Linear static analysis
class LinearStatic(Analysis):
    '''
        Analyse a linear static load case
    '''
    def __init__(self,incrementManager=None, solvingStrategy=None):
        Analysis.__init__(self, incrementManager, solvingStrategy)
        self.lhslist = ["K"]
        self.coeflhs = [1]
        self.rhslist = ["Fext"]
        self.coefrhs = [1]
        

    def __repr__(self):
        return 'linear static analysis'
            
    def start(self, domain):
        ''' Start linear static analysis 
        '''
        # Init increment:
        disp, load, ddisp, dload = self.incrementManager.setNextIncr()
        
        while ddisp or dload:
            # solve:
            self.solvingStrategy.solve(domain, self.lhs, self.rhs, disp+ddisp, load+dload)
            
            # save increment:
            
            
            # set next increment:
            disp, load, ddisp, dload = self.incrementManager.setNextIncr(ddisp, dload)
        
        return domain
        
        
# Non-linear static analysis
class NonLinearStatic(Analysis):
    '''
        Newton-Raphson based solver. Works with the linearized system in an incremental-iterative process.
    '''
    def __init__(self):
        Analysis.__init__(self)
        self.lhslist = ["Kt"]
        self.coeflhs = [1]
        self.rhslist = ["R"]
        self.coefrhs = [-1]
        self.iterative = True

    def __repr__(self):
        return 'nonlinear static analysis'
            
    def start(self):
        ''' Start non-linear static analysis
        '''
        pass


# Buckling analysis
class Buckling(Analysis):
    '''
        Analysis of the buckling modes and eigenvalues 
    '''
    def __init__(self):
        Analysis._init__(self)
        self.lhslist = ["Kt_linear","Kt_nonlinear","Kt_geometric"]
        self.rhslist = []
        
        self.iterative = False
        
    def __repr__(self):
        return 'buckling analysis'
        
    def start(self):
        ''' Start buckling analysis
        '''
        pass


